package games.padinvaders;

import utils.RandomNumber;

import hardware.Display2D;


public class InvadersSquad {

	
	public static final int MOVATYPE_LEFT_RIGHT		= 0;
	public static final int MOVATYPE_RANDOM			= 1;
	
	Invader myInvaders [];
	InvaderProjectile invaderProjectile;
	
	private int xMovieVector;
	
	private int descentCounter;
	private int moveCounter;
	
	private int descentDelay;
	private int movieDelay;
	
	
	private int energy;
	private int charge;
	private int shootCost=100;
	
	
	
	private static byte  formations [][] [] = {{{0,4,Invader.TYPE_SCOUT},{2,4,Invader.TYPE_SCOUT},{4,4,Invader.TYPE_SCOUT},{6,4,Invader.TYPE_SCOUT},
					{0,5,Invader.TYPE_SCOUT},{2,5,Invader.TYPE_SCOUT},{4,5,Invader.TYPE_SCOUT},{6,5,Invader.TYPE_SCOUT},
					{0,6,Invader.TYPE_SCOUT},{2,6,Invader.TYPE_SCOUT},{4,6,Invader.TYPE_SCOUT},{6,6,Invader.TYPE_SCOUT},
					{0,7,Invader.TYPE_SCOUT},{2,7,Invader.TYPE_SCOUT},{4,7,Invader.TYPE_SCOUT},{6,7,Invader.TYPE_SCOUT}},
				
					{{0,4,Invader.TYPE_SCOUT},{2,4,Invader.TYPE_SCOUT},{4,4,Invader.TYPE_SCOUT},{6,4,Invader.TYPE_SCOUT},
					{0,5,Invader.TYPE_FIGHTER},{2,5,Invader.TYPE_FIGHTER},{4,5,Invader.TYPE_FIGHTER},{6,5,Invader.TYPE_FIGHTER},
					{0,6,Invader.TYPE_FIGHTER},{2,6,Invader.TYPE_FIGHTER},{4,6,Invader.TYPE_FIGHTER},{6,6,Invader.TYPE_FIGHTER},
					{0,7,Invader.TYPE_FIGHTER},{2,7,Invader.TYPE_FIGHTER},{4,7,Invader.TYPE_FIGHTER},{6,7,Invader.TYPE_FIGHTER}},
				
					
					
					{{0,7,Invader.TYPE_SCOUT},{1,6,Invader.TYPE_FIGHTER},{2,5,Invader.TYPE_FIGHTER},{3,4,Invader.TYPE_SCOUT},
					{4,5,Invader.TYPE_SCOUT},{5,6,Invader.TYPE_FIGHTER},{6,7,Invader.TYPE_FIGHTER},{3,5,Invader.TYPE_SCOUT},
					{2,6,Invader.TYPE_FIGHTER},{3,6,Invader.TYPE_FIGHTER},{4,6,Invader.TYPE_FIGHTER},{1,7,Invader.TYPE_BOMBER},
					{2,7,Invader.TYPE_BOMBER},{3,7,Invader.TYPE_BOMBER},{4,7,Invader.TYPE_BOMBER},{5,7,Invader.TYPE_BOMBER}},
			
					
					{{2,3,Invader.TYPE_SCOUT},{5,3,Invader.TYPE_SCOUT},{2,4,Invader.TYPE_SCOUT},{5,4,Invader.TYPE_SCOUT},
					{2,5,Invader.TYPE_FIGHTER},{5,5,Invader.TYPE_FIGHTER},{2,6,Invader.TYPE_FIGHTER},{5,6,Invader.TYPE_FIGHTER},
					{2,7,Invader.TYPE_FIGHTER},{5,7,Invader.TYPE_FIGHTER},{2,8,Invader.TYPE_FIGHTER},{5,8,Invader.TYPE_FIGHTER},
					{2,9,Invader.TYPE_BOMBER},{5,9,Invader.TYPE_BOMBER},{2,10,Invader.TYPE_BOMBER},{5,10,Invader.TYPE_BOMBER}}
		
	}; 

	
public InvadersSquad(InvaderProjectile invaderProjectile)
{
	int counter;
	
	this.invaderProjectile=invaderProjectile;
	
	myInvaders = new Invader[16];

	
	for (counter=0;counter<myInvaders.length;counter++)
		{
		myInvaders[counter] = new Invader();
		myInvaders[counter].setVisible(false);
		}
	
	//init(0,0,0);
}	

	
/**
 * @author Tavin
 * 
 * Date 2011.04.11
 * 
 * 
 * @param descentDelay  time delay between for y Vector 
 * @param movieDelay	time delay for X vector
 * @param charge		energy points peer turn 
 */

public void init(int descentDelay,int movieDelay,int level,int charge,int shootCost)
{
	this.descentDelay=descentDelay; 
	this.movieDelay=movieDelay;
	
	this.energy=0;
	this.charge=charge;
	this.shootCost=shootCost;
	
	int invaderCounter;

	xMovieVector=1;
	
	level--;
	
	if (level>3)
		level=3;
	
	for (invaderCounter=0;invaderCounter<myInvaders.length;invaderCounter++)
		{
		myInvaders[invaderCounter].setVisible(true);
		myInvaders[invaderCounter].setPos(formations[level] [invaderCounter] [0],formations[level][invaderCounter] [1]);
		myInvaders[invaderCounter].init(formations[level] [invaderCounter] [2]);
		}
}
	
/**
 * @author Tavin
 * 
 * Date 2011.04.10
 * 
 * Draw members of squad
 */

public void draw()
{
	Invader tmpInvaders [];
	int invaderCounter;
	
	tmpInvaders=myInvaders;	
	
	
	for (invaderCounter=0;invaderCounter<tmpInvaders.length;invaderCounter++)
		{
		tmpInvaders[invaderCounter].draw();
		}	
}

/**
 * @author Tavin
 * 
 * Date 2011.04.11
 * 
 * Check if defender projectile collide with a squad member
 * 
 * @param defenderProjectile
 */

public void checkEnemyFire(DefenderProjectile defenderProjectile)
{
	Invader tmpInvaders [];
	int invaderCounter;
	int damage;
	
	if (!defenderProjectile.isVisible())
		return;
	
	tmpInvaders=myInvaders;	


	for (invaderCounter=0;invaderCounter<tmpInvaders.length;invaderCounter++)
		{
		if (tmpInvaders[invaderCounter].isAlive())
			{
			damage=defenderProjectile.checkDamage(tmpInvaders[invaderCounter].xPos, tmpInvaders[invaderCounter].yPos);
			if (damage>0)
				{
				tmpInvaders[invaderCounter].hit(damage);
				defenderProjectile.kill();
				}
			}
		}		
	

}



/**
 * 
 * @param xPos
 * @param yPos
 * @return
 */
public int checkCollision(int xPos,int yPos)
{

	Invader tmpInvaders [];
	int invaderCounter;
	int damage=0;
	
	tmpInvaders=myInvaders;	


	for (invaderCounter=0;invaderCounter<tmpInvaders.length;invaderCounter++)
		{
		if (tmpInvaders[invaderCounter].isVisible())
			if (tmpInvaders[invaderCounter].match(xPos,yPos))
				{
				tmpInvaders[invaderCounter].setVisible(false);
				damage++;
				//TODO level dependence
				}
		}

	return(damage);
}


/**
 * @author Tavin
 * 
 * Date 2011.104.10
 * 
 * Check if somebody of this squad is visible
 * 
 * @return true if there visible invaders
 */
public boolean somebodyVisible()
{
	Invader tmpInvaders [];
	int invaderCounter;
	
	tmpInvaders=myInvaders;
	
	for (invaderCounter=0;invaderCounter<tmpInvaders.length;invaderCounter++)
		{
		if (tmpInvaders[invaderCounter].isVisible())
			return(true);
		}

	
	return(false);
}





/**
 * @author Tavin
 * 
 * Date 2011.04.11
 * 
 * charge up squad
 */


public void charge()
{
	Invader invaders [];
	int value;
	int copyOfValue;
	int counter;
	
	 energy+=charge;

	 if(invaderProjectile.isVisible())
		 return;
	 
	 invaders=myInvaders;
	 

	 if (energy>shootCost)
	 	{
		 value = RandomNumber.getRange(invaders.length);
		 copyOfValue=value;
		 
		 counter=0;
		 
		while (value>0)
			{
			if (invaders[counter++].isAlive())
				value--;
			
			if (counter>=invaders.length)
				{
				counter=0;
				
				if (value==copyOfValue)
				{
					energy=0;
					return;
				}
					
				}
			
			}
		invaders[counter].fire(invaderProjectile);
		energy-=shootCost;
	 	}
	 


}



/**
 * @author Tavin
 * 
 * Date 2011.04.04
 * 
 * movies squad in x or y position 
 * 
 */

public void movieSquad()
{	
	Invader tmpInvaders [];
	int counter;
	
	tmpInvaders=myInvaders;
	
	
	for(counter=0;counter<tmpInvaders.length;counter++)
		{
		tmpInvaders[counter].process();
		}

	if (moveCounter>movieDelay)
		{
		move();
		moveCounter=0;
		}
	
	
	if (descentCounter>descentDelay)
		{
		descent();
		descentCounter=0;
		}

	moveCounter++;
	descentCounter++;
}



/**
 * @author Tavin
 * 
 * @ gets the min X pos of all Invaders
 */
public int getMinXPos()
{
	Invader tmpInvaders [];
	int invaderCounter;
	int minXPos;
	int tmpPos;
	
	minXPos=Display2D.getColumnCount();
	
	tmpInvaders=myInvaders;	
	

	for (invaderCounter=0;invaderCounter<tmpInvaders.length;invaderCounter++)
		{
		if (tmpInvaders[invaderCounter].isAlive())
			{
			tmpPos=tmpInvaders[invaderCounter].xPos;	

			if (minXPos>tmpPos)
				{
				minXPos=tmpPos;
				}
			}
			
		}	
	
	return(minXPos);
}

/**
 * @author Tavin
 * 
 * @ gets the max X position of all Invaders
 */
public int getMaxXPos()
{
	Invader tmpInvaders [];
	int invaderCounter;
	int maxXPos;
	int tmpPos;
	
	maxXPos=0;
	
	tmpInvaders=myInvaders;	
	

	for (invaderCounter=0;invaderCounter<tmpInvaders.length;invaderCounter++)
		{
		if (tmpInvaders[invaderCounter].isAlive())
			{
			tmpPos=tmpInvaders[invaderCounter].xPos;

			if (maxXPos<tmpPos)
				{
				maxXPos=tmpPos;
				}
			}
		}	
	
	return(maxXPos);
}


public int getMinYPos()
{
	Invader tmpInvaders [];
	int invaderCounter;
	int minYPos;
	int tmpPos;
	
	minYPos=Display2D.getRowCount();
	
	tmpInvaders=myInvaders;	
	

	for (invaderCounter=0;invaderCounter<tmpInvaders.length;invaderCounter++)
		{
		if (tmpInvaders[invaderCounter].isAlive())
			{
			tmpPos=tmpInvaders[invaderCounter].yPos;	

			if (minYPos>tmpPos)
				{
				minYPos=tmpPos;
				}
			}
			
		}	
	
	return(minYPos);
}



public void move()
{
	Invader tmpInvaders [];
	int invaderCounter;
		
	tmpInvaders=myInvaders;	
	


	if (getMaxXPos()>(Display2D.getColumnCount()-2))
		{
		xMovieVector=-1;
		}
	
	if (getMinXPos()<1)
		{
		xMovieVector=1;
		}
	
	for (invaderCounter=0;invaderCounter<tmpInvaders.length;invaderCounter++)
	{
	if (tmpInvaders[invaderCounter].isAlive())
		{
		tmpInvaders[invaderCounter].xPos+=xMovieVector;
		}
	}

}




public void arive()
{
	Invader tmpInvaders [];
	int invaderCounter;
	
	
	tmpInvaders=myInvaders;	
	
	
	for (invaderCounter=0;invaderCounter<tmpInvaders.length;invaderCounter++)
		{
		tmpInvaders[invaderCounter].arrive();
		}
}


public boolean arrived()
{
	return(myInvaders[0].isVisible());	
}





public void descent()
{
	Invader tmpInvaders [];
	int invaderCounter;
	
	tmpInvaders=myInvaders;	
	
	
	for (invaderCounter=0;invaderCounter<tmpInvaders.length;invaderCounter++)
		{
		tmpInvaders[invaderCounter].descent();
		}	
}








}
